import asyncio
from typing import Any, Callable, Coroutine, Optional
import concurrent.futures
from functools import partial

import time

# 导入aiohttp,用于异步http请求

import aiohttp


# 定义异步WebClient类
class AsyncWebClient:

    def __init__(self):

        self.session = None

    # 定义异步上下文管理器进入方法
    async def __aenter__(self):

        # 创建aiohttp客户端会话
        self.session = aiohttp.ClientSession()
        return self

    # 定义异步上下文管理器退出方法
    async def __aexit__(self, exc_type, exc, tb):
        # 关闭aiohttp客户端会话
        await self.session.close()

    # 定义异步获取方法fetch
    async def fetch_data(self, url, name):
        # 打印请求开始信息
        print(f"{name}: 开始请求 {url}")
        try:
            # 以异步方式发起GET请求，10秒超时
            async with self.session.get(url, timeout=10) as response:
                # 读取响应的文本内容
                content = await response.text()
                # 打印请求完成信息，包括状态码和内容长度
                print(f"{name}: 完成，状态码 {response.status}, 长度 {len(content)}")
                # 返回内容长度
                return len(content)
        except Exception as e:
            # 捕获异常并打印错误信息
            print(f"{name}: 错误 {e}")
            # 出错时返回0
            return 0

    # 定义异步方法，用于并发请求多个URL
    async def concurrent_requests(self, urls):
        # 并发请求多个URL
        """并发请求多个URL"""
        # 创建任务列表
        tasks = []

        # 遍历所有URL，创建对应的fetch_url任务
        for i, url in enumerate(urls):
            # 创建单个请求任务
            task = self.fetch_data(url, f"请求{i+1}")
            # 添加任务到任务列表
            tasks.append(task)

        # 打印并发请求开始信息
        print("开始并发请求...")
        # 记录开始时间
        start_time = time.time()

        # 并发执行所有异步请求，等待结果
        results = await asyncio.gather(*tasks)

        # 记录结束时间
        end_time = time.time()
        # 打印所有请求完成和耗时信息
        print(f"所有请求完成，耗时: {end_time - start_time:.2f}秒")
        # 打印所有任务的结果
        print(f"结果: {results}")

        # 返回结果列表
        return results


# 定义异步函数，演示Web客户端的用法
async def web_client():
    # Web客户端演示
    """Web客户端演示"""
    # 准备待请求的URL列表
    urls = [
        "https://httpbin.org/delay/1",
        "https://httpbin.org/delay/2",
        "https://httpbin.org/delay/1",
        "https://httpbin.org/status/200",
        "https://httpbin.org/status/404",
    ]

    # 使用AsyncWebClient异步上下文管理器
    async with AsyncWebClient() as client:
        # 并发请求所有URL
        await client.concurrent_requests(urls)


# 运行Web客户端演示
asyncio.run(web_client())
